#pragma once

#ifndef CFG_h
#define CFG_h

#include "Standards.h"
#include "StmtTable.h"
#include "Schema.h"

class CFG
{
public:
	StmtTable* myST; //!< StmtTable pointer
	//! Constructor (takes in the VarTable and stmtTable)
	CFG(StmtTable*);

	multimap<INDEX,INDEX> forward;
	unordered_multimap<INDEX,unordered_set<INDEX>> backward;
	
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Follows(s1,s2)
		  \param DESIGN_ENTITY design-entity of s1
		  \param NAME s1
		  \param DESIGN_ENTITY design-entity of s2
		  \param NAME s2
		*/
		Schema getSynSyn(DESIGN_ENTITY,NAME,DESIGN_ENTITY,NAME);
		
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Follows(s1,3)
		  \param DESIGN_ENTITY design-entity of s1
		  \param NAME s1
		  \param INDEX 3
		*/
		Schema getSynInt(DESIGN_ENTITY,NAME,INDEX);
		
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Follows(s1,_)
		  \param DESIGN_ENTITY design-entity of s1
		  \param NAME s1
		*/
		Schema getSynUnd(DESIGN_ENTITY,NAME);

		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Follows(3,s2)
		  \param INDEX 3
		  \param DESIGN_ENTITY design-entity of s2
		  \param NAME s2
		*/
		Schema getIntSyn(INDEX,DESIGN_ENTITY,NAME);
		
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Follows(3,4)
		  \param INDEX 3
		  \param INDEX 4
		*/
		Schema getIntInt(INDEX,INDEX);
		
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Follows(3,_)
		  \param INDEX 3
		*/
		Schema getIntUnd(INDEX);

		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Follows(_,3)
		  \param INDEX 3
		*/
		Schema getUndInt(INDEX);
		
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Follows(_,s2)
		  \param DESIGN_ENTITY design-entity of s2
		  \param NAME s2
		*/
		Schema getUndSyn(DESIGN_ENTITY,NAME);
		
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Follows(_,_) 
		*/
		Schema getUndUnd();

		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Follows(s1,3)
		  \param DESIGN_ENTITY design-entity of s1
		  \param NAME s1
		  \param INDEX 3
		*/
		Schema getSynIntClosure(DESIGN_ENTITY,NAME,INDEX);

		Schema getIntIntClosure(INDEX, INDEX);

	void printAll();
	void refineNext();
};
#endif